cmake_minimum_required (VERSION 3.8.2)
project (ffead-cpp-4.0)
include(CheckIncludeFile)
include(CheckIncludeFileCXX)
include(CheckSymbolExists)

set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_SKIP_BUILD_RPATH true)
if(POLICY CMP0068)
  cmake_policy(SET CMP0068 NEW)
endif()

option(DEBUG "Generate with debug options" OFF)
option(MOD_MEMORY "Enable Memory Cache module" ON)
option(MOD_MEMCACHED "Enable Memcached Cache module" OFF)
option(MOD_REDIS "Enable Redis Cache module" OFF)
option(MOD_SDORM_SQL "Enable SQL Sdorm module" ON)
option(MOD_SDORM_MONGO "Enable Mongo Sdorm module" OFF)
option(MOD_SER_BIN "Enable Binary Serialization module" OFF)
option(MOD_JOBS "Enable Jobs module" ON)
option(MOD_APACHE "Enable Apache module" OFF)
option(MOD_NGINX "Enable Nginx module" OFF)
option(SRV_ALL "Build All inbuilt HTTP Server Engines" OFF)
option(SRV_EMB "Embedded Http Server Engine" OFF)
option(SRV_CINATRA "Cinatra Http Server Engine" OFF)
option(SRV_LITHIUM "Lithium Http Server Engine" OFF)
option(SRV_DROGON "Drogon Http Server Engine" OFF)

if(NOT CINATRA_INCLUDES)
	set(CINATRA_INCLUDES "/cinatra/include")
endif()
if(NOT SSL_INC_DIR)
	set(SSL_INC_DIR "/usr/local/opt/openssl/include")
endif()
if(NOT SSL_LIB)
	set(SSL_LIB "/usr/local/opt/openssl/lib/libssl.dylib")
endif()
if(NOT CRYPTO_LIB)
	set(CRYPTO_LIB "/usr/local/opt/openssl/lib/libcrypto.dylib")
endif()

set(CMAKE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/src)
set(CMAKE_VERBOSE_MAKEFILE off)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
if(CMAKE_INC_PATH)
	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_INC_PATH}/include -Wall -Wno-unknown-pragmas -Wno-delete-incomplete -Wno-deprecated")
else()
	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/usr/local/include -Wall -Wno-unknown-pragmas -Wno-delete-incomplete -Wno-deprecated")
endif()
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-undefined,error")
set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR})

if(DEBUG)
	set(CMAKE_BUILD_TYPE DEBUG)
	set(TO_REPLACE_DEBUG "set(CMAKE_BUILD_TYPE DEBUG)")
	if (APPLE)
		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
	endif()
else()
	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
endif(DEBUG)
if(CMAKE_INC_PATH)
	include_directories("${CMAKE_INC_PATH}/include" "${CMAKE_SOURCE_DIR}/modules/common" "${CMAKE_SOURCE_DIR}/modules/cache" "${CMAKE_SOURCE_DIR}/modules/client-util")
else()
	include_directories("/usr/local/include" "${CMAKE_SOURCE_DIR}/modules/common" "${CMAKE_SOURCE_DIR}/modules/cache" "${CMAKE_SOURCE_DIR}/modules/client-util")
endif()
include_directories("${CMAKE_SOURCE_DIR}/modules/http" "${CMAKE_SOURCE_DIR}/modules/http/http11" "${CMAKE_SOURCE_DIR}/modules/http/http20" "${CMAKE_SOURCE_DIR}/modules/ioc")
include_directories("${CMAKE_SOURCE_DIR}/modules/jobs" "${CMAKE_SOURCE_DIR}/modules/reflection" "${CMAKE_SOURCE_DIR}/modules/sdorm" "${CMAKE_SOURCE_DIR}/modules/search")
include_directories("${CMAKE_SOURCE_DIR}/modules/serialization" "${CMAKE_SOURCE_DIR}/modules/serialization/xml" "${CMAKE_SOURCE_DIR}/modules/serialization/json")
include_directories("${CMAKE_SOURCE_DIR}/modules/server-util" "${CMAKE_SOURCE_DIR}/modules/ssl" "${CMAKE_SOURCE_DIR}/modules/threads")
if(CMAKE_INC_PATH)
	include_directories("${CMAKE_SOURCE_DIR}/framework" "${CMAKE_INC_PATH}/include")
else()
	include_directories("${CMAKE_SOURCE_DIR}/framework")
endif()

find_package(Threads)

# CMake does not distinguish Linux from other Unices.
STRING (REGEX MATCH ".*Linux.*" PROJECT_OS_LINUX ${CMAKE_SYSTEM_NAME})
# Nor *BSD
STRING (REGEX MATCH ".*BSD.*" PROJECT_OS_BSD ${CMAKE_SYSTEM_NAME})
# Or Solaris. I'm seeing a trend, here
STRING (REGEX MATCH ".*SunOS.*" PROJECT_OS_SOLARIS ${CMAKE_SYSTEM_NAME})

set(HAVE_WINREGEX "")

if (UNIX)
	IF (PROJECT_OS_BSD)
		set(OS_BSD 1)
		set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/local/v6/lib")
    ELSEIF (PROJECT_OS_SOLARIS)
    	set(OS_SOLARIS 1)
    	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthreads")
		set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lsocket -lnsl")
    ELSE()
    	set(OS_LINUX 1)
    ENDIF()
    if(CMAKE_INC_PATH)
		set(CMAKE_REQUIRED_INCLUDES "${CMAKE_INC_PATH}/include")
	else()
		set(CMAKE_REQUIRED_INCLUDES "/usr/local/include")
	endif()
endif (UNIX)
if (APPLE)
	set(OS_DARWIN 1)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${SSL_INC_DIR}")
	set(CMAKE_REQUIRED_INCLUDES "${SSL_INC_DIR}" "/usr/local/include")
	include_directories("${SSL_INC_DIR}" "/usr/local/include")
endif (APPLE)
if (MINGW)
	set(OS_MINGW 1)
	set(USE_WIN_IOCP 1)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__USE_MINGW_ANSI_STDIO=1")
    if(CMAKE_INC_PATH)
		set(CMAKE_REQUIRED_INCLUDES "${CMAKE_INC_PATH}/include")
	else()
		set(CMAKE_REQUIRED_INCLUDES "/usr/local/include")
	endif()
	include_directories("${CMAKE_SOURCE_DIR}/modules/wepoll")
	set(HAVE_WSOCK32 wsock32)
	set(HAVE_WS232 ws2_32)
	if (WIN32 AND CMAKE_HOST_WIN32)
		set(HAVE_WINREGEX regex)
	endif()
	CHECK_INCLUDE_FILE("dlfcn.h" HAVE_DLINC)
	if(NOT HAVE_DLINC)
		message(FATAL_ERROR "dlfcn includes not found")
	endif()
	FIND_LIBRARY(HAVE_DLLIB dl)
	if(NOT HAVE_DLLIB)
		message(FATAL_ERROR "dl library not found")
	endif()
endif (MINGW)
if(CYGWIN)
	set(CYGWIN 1)
	if(CMAKE_INC_PATH)
		set(CMAKE_REQUIRED_INCLUDES "${CMAKE_INC_PATH}/include")
	else()
		set(CMAKE_REQUIRED_INCLUDES "/usr/local/include")
	endif()
endif(CYGWIN)
if(ANDROID)
	set(OS_ANDROID 1)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__USE_MINGW_ANSI_STDIO=1")
    if(CMAKE_INC_PATH)
		set(CMAKE_REQUIRED_INCLUDES "${CMAKE_INC_PATH}/include")
	else()
		set(CMAKE_REQUIRED_INCLUDES "/usr/local/include")
	endif()
	set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
endif(ANDROID)

if(CMAKE_INC_PATH)
	set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_INC_PATH}/lib")
else()
	set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/local/lib")
endif()

set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
check_symbol_exists(accept4	"sys/socket.h"	HAVE_ACCEPT4)

include(CheckCSourceCompiles)
CHECK_C_SOURCE_COMPILES("
	#include <sys/socket.h>
	#include <netinet/in.h>
	#include <netinet/tcp.h>
	int main() { return TCP_QUICKACK; }"
HAVE_TCP_QUICKACK)

include(CheckCSourceCompiles)
CHECK_C_SOURCE_COMPILES("
	#include <sys/socket.h>
	#include <netinet/in.h>
	#include <netinet/tcp.h>
	int main() { return TCP_DEFER_ACCEPT; }"
HAVE_TCP_DEFER_ACCEPT)

include(CheckCSourceCompiles)
CHECK_C_SOURCE_COMPILES("
	#include <sys/socket.h>
	#include <netinet/in.h>
	#include <netinet/tcp.h>
	int main() { return TCP_FASTOPEN; }"
HAVE_TCP_FASTOPEN)

CHECK_INCLUDE_FILE("regex.h" HAVE_REGEX)
if(NOT HAVE_REGEX)
	CHECK_INCLUDE_FILE("pcreposix.h" HAVE_PCRE_POSIX_REGEX)
	if(NOT HAVE_PCRE_POSIX_REGEX)
		message(FATAL_ERROR "regex includes not found")
	endif()
	FIND_LIBRARY(HAVE_PCREPOSIXLIB pcreposix)
	if(NOT HAVE_PCREPOSIXLIB)
		message(FATAL_ERROR "pcreposix library not found")
	endif()
endif()

FIND_LIBRARY(HAVE_CURLLIB curl)
if(NOT HAVE_CURLLIB)
	message(FATAL_ERROR "curl library not found")
endif()
FIND_LIBRARY(HAVE_ZLIB z)
if(NOT HAVE_ZLIB)
	message(FATAL_ERROR "z library not found")
endif()

CHECK_INCLUDE_FILE("openssl/ssl.h" HAVE_SSLINC)
if(NOT HAVE_SSLINC)
	message(FATAL_ERROR "openssl includes not found")
endif()
if (APPLE)
	set(HAVE_SSLLIB ${SSL_LIB})
	set(HAVE_CRYPTOLIB ${CRYPTO_LIB})
else()
	FIND_LIBRARY(HAVE_SSLLIB ssl)
	if(NOT HAVE_SSLLIB)
		message(FATAL_ERROR "ssl library not found")
	endif()
	FIND_LIBRARY(HAVE_CRYPTOLIB crypto)
	if(NOT HAVE_CRYPTOLIB)
		message(FATAL_ERROR "cypto library not found")
	endif()
endif()
#FIND_LIBRARY(HAVE_TBBLIB tbb)
#if(NOT HAVE_TBBLIB)
#	message(FATAL_ERROR "tbb library not found")
#endif()
#CHECK_INCLUDE_FILE_CXX("tbb/concurrent_hash_map.h" HAVE_TBBINC)
#if(NOT HAVE_TBBINC)
#	message(FATAL_ERROR "tbb includes not found")
#endif()
CHECK_INCLUDE_FILE_CXX("libcuckoo/cuckoohash_map.hh" HAVE_CKOHMINC)
if(NOT HAVE_CKOHMINC)
	message(FATAL_ERROR "libcuckoo includes not found")
endif()
FIND_LIBRARY(HAVE_UUIDLIB uuid)
if(NOT HAVE_UUIDLIB)
	FIND_LIBRARY(HAVE_UUIDLIB ossp-uuid)
	if(NOT HAVE_UUIDLIB)
		message(FATAL_ERROR "uuid library not found")
	endif()
endif()
CHECK_INCLUDE_FILE("execinfo.h" HAVE_EXECINFOINC)

CHECK_INCLUDE_FILE("sys/epoll.h" USE_EPOLL)
CHECK_INCLUDE_FILE("sys/event.h" USE_KQUEUE)
CHECK_INCLUDE_FILE("port.h" USE_EVPORT)
CHECK_INCLUDE_FILE("sys/devpoll.h" USE_DEVPOLL)
CHECK_INCLUDE_FILE("sys/poll.h" USE_POLL)
CHECK_INCLUDE_FILE("sys/select.h" USE_SELECT)

if(MOD_MEMORY)
	set(INC_MEMORYCACHE 1)
	include_directories("${CMAKE_SOURCE_DIR}/modules/cache/memory")
endif(MOD_MEMORY)
if(MOD_REDIS)
	set(INC_REDISCACHE 1)
	CHECK_INCLUDE_FILE("hiredis/hiredis.h" HAVE_REDISINC)
	FIND_LIBRARY(HAVE_REDISLIB hiredis)
	if(NOT HAVE_REDISLIB)
		message(FATAL_ERROR "hiredis library not found")
	endif()
	include_directories("${CMAKE_SOURCE_DIR}/modules/cache/redis")
endif(MOD_REDIS)
if(MOD_MEMCACHED)
	set(INC_MEMCACHED 1)
	CHECK_INCLUDE_FILE("libmemcached/memcached.h" HAVE_MEMCACHEDINC)
	FIND_LIBRARY(HAVE_MEMCACHEDLIB memcached)
	if(NOT HAVE_MEMCACHEDLIB)
		message(FATAL_ERROR "memcached library not found")
	endif()
	FIND_LIBRARY(HAVE_MEMCACHEDUTILLIB memcachedutil)
	if(NOT HAVE_MEMCACHEDUTILLIB)
		message(FATAL_ERROR "memcachedutil library not found")
	endif()
	include_directories("${CMAKE_SOURCE_DIR}/modules/cache/memcached")
endif(MOD_MEMCACHED)

if(MOD_SDORM_SQL)
	set(INC_SDORM 1)
	set(INC_SDORM_SQL 1)
	IF (PROJECT_OS_BSD)
		CHECK_INCLUDE_FILE("uuid.h" HAVE_BSDUUIDINC)
		if(NOT HAVE_BSDUUIDINC)
			CHECK_INCLUDE_FILE("uuid/uuid.h" HAVE_UUIDINC)
			if(NOT HAVE_UUIDINC)
				message(FATAL_ERROR "uuid includes not found")
			endif()
		endif()
	else()
		CHECK_INCLUDE_FILE("uuid.h" HAVE_OSSPUUIDINC)
		if(NOT HAVE_OSSPUUIDINC)
			CHECK_INCLUDE_FILE("uuid/uuid.h" HAVE_UUIDINC)
			if(NOT HAVE_UUIDINC)
				message(FATAL_ERROR "uuid includes not found")
			endif()
		endif()
	endif()
	CHECK_INCLUDE_FILE("sql.h" HAVE_SQLINC)
	if(NOT HAVE_SQLINC)
		message(FATAL_ERROR "odbc includes not found")
	endif()
	FIND_LIBRARY(HAVE_ODBCLIB odbc)
	if(NOT HAVE_ODBCLIB)
		message(FATAL_ERROR "odbc library not found")
	endif()
	find_package(PostgreSQL)
	if(PostgreSQL_LIBRARIES)
		set(HAVE_LIBPQ ${PostgreSQL_LIBRARIES})
	else()
		set(HAVE_LIBPQ "")
	endif(PostgreSQL_LIBRARIES)
	#CHECK_INCLUDE_FILE("libpq-fe.h" HAVE_PQHDR)
	#FIND_LIBRARY(HAVE_LIBPQ pq)
	if(HAVE_LIBPQ AND PostgreSQL_INCLUDE_DIRS)
		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${PostgreSQL_INCLUDE_DIRS}")
		include_directories("${CMAKE_SOURCE_DIR}/modules/sdorm/sql/libpq" "${PostgreSQL_INCLUDE_DIRS}")
	else()
		set(HAVE_LIBPQ "")
	endif()
	include_directories("${CMAKE_SOURCE_DIR}/modules/sdorm/sql")
else()
	set(HAVE_LIBPQ "")
endif(MOD_SDORM_SQL)
if(MOD_SDORM_MONGO)
	set(INC_SDORM 1)
	set(INC_SDORM_MONGO 1)
	IF (PROJECT_OS_BSD)
		CHECK_INCLUDE_FILE("uuid.h" HAVE_BSDUUIDINC)
		if(NOT HAVE_BSDUUIDINC)
			CHECK_INCLUDE_FILE("uuid/uuid.h" HAVE_UUIDINC)
			if(NOT HAVE_UUIDINC)
				message(FATAL_ERROR "uuid includes not found")
			endif()
		endif()
	else()
		CHECK_INCLUDE_FILE("uuid.h" HAVE_OSSPUUIDINC)
		if(NOT HAVE_OSSPUUIDINC)
			CHECK_INCLUDE_FILE("uuid/uuid.h" HAVE_UUIDINC)
			if(NOT HAVE_UUIDINC)
				message(FATAL_ERROR "uuid includes not found")
			endif()
		endif()
	endif()
	if(CMAKE_INC_PATH)
		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_INC_PATH}/include/libmongoc-1.0 -I${CMAKE_INC_PATH}/include/libbson-1.0 -D__USE_MINGW_ANSI_STDIO=1")
		set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_INC_PATH}/include/libmongoc-1.0 -I${CMAKE_INC_PATH}/include/libbson-1.0 -D__USE_MINGW_ANSI_STDIO=1")
		set(CMAKE_REQUIRED_INCLUDES "${CMAKE_INC_PATH}/include/libmongoc-1.0" "${CMAKE_INC_PATH}/include/libbson-1.0" )
		include_directories("${CMAKE_INC_PATH}/include/libmongoc-1.0" "${CMAKE_INC_PATH}/include/libbson-1.0")
	else()
		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/usr/include/libmongoc-1.0 -I/usr/include/libbson-1.0 -I/usr/local/include/libmongoc-1.0 -I/usr/local/include/libbson-1.0 -D__USE_MINGW_ANSI_STDIO=1")
		set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I/usr/include/libmongoc-1.0 -I/usr/include/libbson-1.0 -I/usr/local/include/libmongoc-1.0 -I/usr/local/include/libbson-1.0 -D__USE_MINGW_ANSI_STDIO=1")
		set(CMAKE_REQUIRED_INCLUDES "/usr/include/libmongoc-1.0" "/usr/include/libbson-1.0" "/usr/local/include/libmongoc-1.0" "/usr/local/include/libbson-1.0")
		include_directories("/usr/include/libmongoc-1.0" "/usr/include/libbson-1.0" "/usr/local/include/libmongoc-1.0" "/usr/local/include/libbson-1.0")
	endif()
	CHECK_INCLUDE_FILE("mongoc.h" HAVE_MONGOINC)
	if(NOT HAVE_MONGOINC)
		message(FATAL_ERROR "mongoc includes not found")
	endif()
	FIND_LIBRARY(HAVE_MONGOCLIB mongoc-1.0)
	if(NOT HAVE_MONGOCLIB)
		message(FATAL_ERROR "mongoc-1.0 library not found")
	endif()
	CHECK_INCLUDE_FILE("bson.h" HAVE_BSONINC)
	if(NOT HAVE_BSONINC)
		message(FATAL_ERROR "bson includes not found")
	endif()
	FIND_LIBRARY(HAVE_BSONLIB bson-1.0)
	if(NOT HAVE_BSONLIB)
		message(FATAL_ERROR "bson-1.0 library not found")
	endif()
	include_directories("${CMAKE_SOURCE_DIR}/modules/sdorm/mongo")
endif(MOD_SDORM_MONGO)
if(MOD_SER_BIN)
	set(INC_BINSER 1)
	include_directories("${CMAKE_SOURCE_DIR}/modules/serialization/binary")
endif(MOD_SER_BIN)
if(MOD_JOBS)
	set(INC_JOBS 1)
	include_directories("${CMAKE_SOURCE_DIR}/modules/jobs")
endif(MOD_JOBS)

set(TO_REPLACE_CPPFLAGS ${CMAKE_CXX_FLAGS})
set(TO_REPLACE_LDFLAGS ${CMAKE_EXE_LINKER_FLAGS})
set(TO_CMAKE_SOURCE_DIR "\$\{CMAKE_SOURCE_DIR\}")
set(TO_PROJECT_SOURCE_DIR "\$\{PROJECT_SOURCE_DIR\}")
set(TO_INTER_SOURCES "\$\{INTER_SOURCES\}")
set(TO_DINTER_SOURCES "\$\{DINTER_SOURCES\}")
set(TO_INTER_DINTER_LIBRARIES "\$\{INTER_DINTER_LIBRARIES\}")
set(TO_HAVE_MODULES "\$\{HAVE_FFEAD_MODULES_LIB\}")
set(TO_HAVE_FRAMEWORK "\$\{HAVE_FFEAD_FRWRK_LIB\}")
set(TO_INTER_DINTER_INCLUDES "\$\{INTER_DINTER_INCLUDES\}")

if(SRV_ALL)
	CHECK_INCLUDE_FILE("cinatra.hpp" CINATRA_INC)
	set(Boost_USE_STATIC_LIBS OFF)
	set(Boost_USE_STATIC_RUNTIME OFF)
	set(Boost_USE_MULTITHREADED ON)
	find_package(Boost REQUIRED COMPONENTS system context)
	include_directories(${Boost_INCLUDE_DIRS})
	find_package(PkgConfig REQUIRED)
	pkg_check_modules(JSONCPP jsoncpp)
	if(CMAKE_INC_PATH)
		set(CMAKE_JSONCPP_INC "${CMAKE_INC_PATH}/include/jsoncpp")
	else()
		set(CMAKE_JSONCPP_INC "/usr/local/include/jsoncpp" "/usr/include/jsoncpp")
	endif()
	FIND_LIBRARY(HAVE_JSONCPP jsoncpp)
	if(NOT HAVE_JSONCPP)
		message(FATAL_ERROR "jsoncpp library not found")
	endif()
	CHECK_INCLUDE_FILE("drogon/drogon.h" DROGON_INC)
	CHECK_INCLUDE_FILE("drogon/orm/DbClient.h" DROGON_ORM_INC)
	CHECK_INCLUDE_FILE("trantor/net/EventLoop.h" TRANTOR_INC)
	FIND_LIBRARY(HAVE_DROGONLIB drogon)
	if(NOT HAVE_DROGONLIB)
		message(FATAL_ERROR "drogon library not found")
	endif()
	FIND_LIBRARY(HAVE_TRANTORLIB trantor)
	if(NOT HAVE_TRANTORLIB)
		message(FATAL_ERROR "trantor library not found")
	endif()
elseif(SRV_EMB)
	set(SRV_EMB 1)
elseif(SRV_CINATRA)
	set(SRV_CINATRA 1)
	CHECK_INCLUDE_FILE("cinatra.hpp" CINATRA_INC)
	set(Boost_USE_STATIC_LIBS OFF)
	set(Boost_USE_STATIC_RUNTIME OFF)
	set(Boost_USE_MULTITHREADED ON)
	find_package(Boost REQUIRED COMPONENTS system)
	include_directories(${Boost_INCLUDE_DIRS})
elseif(SRV_LITHIUM)
	set(SRV_LITHIUM 1)
	set(Boost_USE_STATIC_LIBS OFF)
	set(Boost_USE_STATIC_RUNTIME OFF)
	set(Boost_USE_MULTITHREADED ON)
	find_package(Boost REQUIRED COMPONENTS context)
	include_directories(${Boost_INCLUDE_DIRS})
elseif(SRV_DROGON)
	set(SRV_DROGON 1)
	find_package(PkgConfig REQUIRED)
	pkg_check_modules(JSONCPP jsoncpp)
	if(CMAKE_INC_PATH)
		set(CMAKE_JSONCPP_INC "${CMAKE_INC_PATH}/include/jsoncpp")
	else()
		set(CMAKE_JSONCPP_INC "/usr/local/include/jsoncpp" "/usr/include/jsoncpp")
	endif()
	FIND_LIBRARY(HAVE_JSONCPP jsoncpp)
	if(NOT HAVE_JSONCPP)
		message(FATAL_ERROR "jsoncpp library not found")
	endif()
	CHECK_INCLUDE_FILE("drogon/drogon.h" DROGON_INC)
	CHECK_INCLUDE_FILE("drogon/orm/DbClient.h" DROGON_ORM_INC)
	CHECK_INCLUDE_FILE("trantor/net/EventLoop.h" TRANTOR_INC)
	FIND_LIBRARY(HAVE_DROGONLIB drogon)
	if(NOT HAVE_DROGONLIB)
		message(FATAL_ERROR "drogon library not found")
	endif()
	FIND_LIBRARY(HAVE_TRANTORLIB trantor)
	if(NOT HAVE_TRANTORLIB)
		message(FATAL_ERROR "trantor library not found")
	endif()
endif()

configure_file (
  "${PROJECT_SOURCE_DIR}/src/modules/common/AppDefines.h.in.cm"
  "${PROJECT_SOURCE_DIR}/src/modules/common/AppDefines.h"
)
configure_file (
  "${PROJECT_SOURCE_DIR}/rtdcf/CMakeLists.txt.template.in"
  "${PROJECT_SOURCE_DIR}/rtdcf/CMakeLists.txt.template"
)

add_subdirectory(${PROJECT_SOURCE_DIR}/src/modules)
add_subdirectory(${PROJECT_SOURCE_DIR}/src/framework)
add_subdirectory(${PROJECT_SOURCE_DIR}/tests)

#Add any web diectories here
add_subdirectory(${PROJECT_SOURCE_DIR}/web/default)
add_subdirectory(${PROJECT_SOURCE_DIR}/web/flexApp)
add_subdirectory(${PROJECT_SOURCE_DIR}/web/oauthApp)
add_subdirectory(${PROJECT_SOURCE_DIR}/web/markers)
add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark)
add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um)
add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq)
add_subdirectory(${PROJECT_SOURCE_DIR}/web/peer-server)
if(MOD_APACHE)
	add_subdirectory(${PROJECT_SOURCE_DIR}/modules/apache_mod_ffeadcpp)
endif()
if(MOD_NGINX)
	add_subdirectory(${PROJECT_SOURCE_DIR}/modules/nginx_mod_ffeadcpp)
endif()

if(SRV_ALL)
	add_executable(ffead-cpp src/server/embedded/CHServer.cpp)
	set_property(TARGET ffead-cpp PROPERTY POSITION_INDEPENDENT_CODE ON)
	target_link_libraries(ffead-cpp ffead-modules ffead-framework ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${HAVE_PCREPOSIXLIB} ${HAVE_UUIDLIB} ${HAVE_CURLLIB} ${HAVE_SSLLIB} ${HAVE_REDISLIB} ${HAVE_MEMCACHEDLIB} ${HAVE_MEMCACHEDUTILLIB} ${HAVE_ODBCLIB} ${HAVE_MONGOCLIB} ${HAVE_BSONLIB} ${HAVE_ZLIB} ${HAVE_CRYPTOLIB})
	
	include_directories("${CINATRA_INCLUDES}")
	add_executable(ffead-cpp-cinatra src/server/cinatra/CinatraServer.cpp)
	find_package(Boost 1.65 REQUIRED COMPONENTS system)
	set_property(TARGET ffead-cpp-cinatra PROPERTY POSITION_INDEPENDENT_CODE ON)
	target_link_libraries(ffead-cpp-cinatra ffead-modules ffead-framework stdc++fs ${Boost_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${HAVE_PCREPOSIXLIB} ${HAVE_UUIDLIB} ${HAVE_CURLLIB} ${HAVE_SSLLIB} ${HAVE_REDISLIB} ${HAVE_MEMCACHEDLIB} ${HAVE_MEMCACHEDUTILLIB} ${HAVE_ODBCLIB} ${HAVE_MONGOCLIB} ${HAVE_BSONLIB} ${HAVE_ZLIB} ${HAVE_CRYPTOLIB})
	
	add_executable(ffead-cpp-lithium src/server/lithium/LithiumServer.cpp)
	set_property(TARGET ffead-cpp-lithium PROPERTY POSITION_INDEPENDENT_CODE ON)
	target_link_libraries(ffead-cpp-lithium ffead-modules ffead-framework boost_context ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${HAVE_PCREPOSIXLIB} ${HAVE_UUIDLIB} ${HAVE_CURLLIB} ${HAVE_SSLLIB} ${HAVE_REDISLIB} ${HAVE_MEMCACHEDLIB} ${HAVE_MEMCACHEDUTILLIB} ${HAVE_ODBCLIB} ${HAVE_MONGOCLIB} ${HAVE_BSONLIB} ${HAVE_ZLIB} ${HAVE_CRYPTOLIB})
	include_directories("${CMAKE_JSONCPP_INC}")
	
	add_executable(ffead-cpp-drogon src/server/drogon/DrogonServer.cpp)
	set_property(TARGET ffead-cpp-drogon PROPERTY POSITION_INDEPENDENT_CODE ON)
	target_link_libraries(ffead-cpp-drogon ffead-modules ffead-framework ${HAVE_DROGONLIB} ${HAVE_TRANTORLIB} ${HAVE_JSONCPP} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${HAVE_PCREPOSIXLIB} ${HAVE_UUIDLIB} ${HAVE_CURLLIB} ${HAVE_SSLLIB} ${HAVE_REDISLIB} ${HAVE_MEMCACHEDLIB} ${HAVE_MEMCACHEDUTILLIB} ${HAVE_ODBCLIB} ${HAVE_MONGOCLIB} ${HAVE_BSONLIB} ${HAVE_ZLIB} ${HAVE_CRYPTOLIB})
elseif(SRV_EMB)
	add_executable(ffead-cpp src/server/embedded/CHServer.cpp)
	set_property(TARGET ffead-cpp PROPERTY POSITION_INDEPENDENT_CODE ON)
	target_link_libraries(ffead-cpp ffead-modules ffead-framework ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${HAVE_PCREPOSIXLIB} ${HAVE_UUIDLIB} ${HAVE_CURLLIB} ${HAVE_SSLLIB} ${HAVE_REDISLIB} ${HAVE_MEMCACHEDLIB} ${HAVE_MEMCACHEDUTILLIB} ${HAVE_ODBCLIB} ${HAVE_MONGOCLIB} ${HAVE_BSONLIB} ${HAVE_ZLIB} ${HAVE_CRYPTOLIB})
elseif(SRV_CINATRA)
	include_directories("${CINATRA_INCLUDES}")
	add_executable(ffead-cpp src/server/cinatra/CinatraServer.cpp)
	find_package(Boost 1.65 REQUIRED COMPONENTS system)
	set_property(TARGET ffead-cpp PROPERTY POSITION_INDEPENDENT_CODE ON)
	target_link_libraries(ffead-cpp ffead-modules ffead-framework stdc++fs ${Boost_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${HAVE_PCREPOSIXLIB} ${HAVE_UUIDLIB} ${HAVE_CURLLIB} ${HAVE_SSLLIB} ${HAVE_REDISLIB} ${HAVE_MEMCACHEDLIB} ${HAVE_MEMCACHEDUTILLIB} ${HAVE_ODBCLIB} ${HAVE_MONGOCLIB} ${HAVE_BSONLIB} ${HAVE_ZLIB} ${HAVE_CRYPTOLIB})
elseif(SRV_LITHIUM)
	add_executable(ffead-cpp src/server/lithium/LithiumServer.cpp)
	set_property(TARGET ffead-cpp PROPERTY POSITION_INDEPENDENT_CODE ON)
	target_link_libraries(ffead-cpp ffead-modules ffead-framework boost_context ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${HAVE_PCREPOSIXLIB} ${HAVE_UUIDLIB} ${HAVE_CURLLIB} ${HAVE_SSLLIB} ${HAVE_REDISLIB} ${HAVE_MEMCACHEDLIB} ${HAVE_MEMCACHEDUTILLIB} ${HAVE_ODBCLIB} ${HAVE_MONGOCLIB} ${HAVE_BSONLIB} ${HAVE_ZLIB} ${HAVE_CRYPTOLIB})
elseif(SRV_DROGON)
	include_directories("${CMAKE_JSONCPP_INC}")
	add_executable(ffead-cpp src/server/drogon/DrogonServer.cpp)
	set_property(TARGET ffead-cpp PROPERTY POSITION_INDEPENDENT_CODE ON)
	target_link_libraries(ffead-cpp ffead-modules ffead-framework ${HAVE_DROGONLIB} ${HAVE_TRANTORLIB} ${HAVE_JSONCPP} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${HAVE_PCREPOSIXLIB} ${HAVE_UUIDLIB} ${HAVE_CURLLIB} ${HAVE_SSLLIB} ${HAVE_REDISLIB} ${HAVE_MEMCACHEDLIB} ${HAVE_MEMCACHEDUTILLIB} ${HAVE_ODBCLIB} ${HAVE_MONGOCLIB} ${HAVE_BSONLIB} ${HAVE_ZLIB} ${HAVE_CRYPTOLIB})
endif()

MESSAGE( STATUS "CMAKE_REQUIRED_INCLUDES: " ${CMAKE_REQUIRED_INCLUDES} )
MESSAGE( STATUS "CMAKE_CXX_FLAGS: " ${CMAKE_CXX_FLAGS} )
MESSAGE( STATUS "CMAKE_EXE_LINKER_FLAGS: " ${CMAKE_EXE_LINKER_FLAGS} )
MESSAGE( STATUS "CMAKE_INSTALL_PREFIX: " ${CMAKE_INSTALL_PREFIX} )
if(SRV_CINATRA)
	MESSAGE( STATUS "CINATRA_INCLUDES: " ${CINATRA_INCLUDES} )
elseif (SRV_ALL)
	MESSAGE( STATUS "CINATRA_INCLUDES: " ${CINATRA_INCLUDES} )
endif()
if (APPLE)
	MESSAGE( STATUS "SSL_LIB: " ${SSL_LIB} )
	MESSAGE( STATUS "CRYPTO_LIB: " ${CRYPTO_LIB} )
endif()

install(CODE "execute_process(COMMAND rm -rf ${PROJECT_NAME}-bin)")
install(DIRECTORY DESTINATION "${PROJECT_NAME}-bin")
install(DIRECTORY DESTINATION "${PROJECT_NAME}-bin/resources")
install(DIRECTORY DESTINATION "${PROJECT_NAME}-bin/lib")
install(DIRECTORY DESTINATION "${PROJECT_NAME}-bin/public")
install(DIRECTORY DESTINATION "${PROJECT_NAME}-bin/include")
install(DIRECTORY DESTINATION "${PROJECT_NAME}-bin/rtdcf")
install(DIRECTORY DESTINATION "${PROJECT_NAME}-bin/web")
install(DIRECTORY DESTINATION "${PROJECT_NAME}-bin/tmp")
install(DIRECTORY DESTINATION "${PROJECT_NAME}-bin/logs")
install(DIRECTORY DESTINATION "${PROJECT_NAME}-bin/tests")
install(DIRECTORY ${PROJECT_SOURCE_DIR}/resources/ DESTINATION ${PROJECT_NAME}-bin/resources)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/public/ DESTINATION ${PROJECT_NAME}-bin/public)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/rtdcf/ DESTINATION ${PROJECT_NAME}-bin/rtdcf)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/web/ DESTINATION ${PROJECT_NAME}-bin/web)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/tests/ DESTINATION ${PROJECT_NAME}-bin/tests)
if(CYGWIN OR MINGW)
	if(CYGWIN)
		install(FILES ${PROJECT_BINARY_DIR}/src/modules/cygffead-modules${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/src/framework/cygffead-framework${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/default/cygdefault${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/flexApp/cygflexApp${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/oauthApp/cygoauthApp${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/markers/cygmarkers${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark/cygte_benchmark${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um/cygte_benchmark_um${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq/cygte_benchmark_um_pq${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/peer-server/cygpeer_server${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/src/modules/libffead-modules${CMAKE_SHARED_LIBRARY_SUFFIX}.a DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/src/framework/libffead-framework${CMAKE_SHARED_LIBRARY_SUFFIX}.a DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/default/libdefault${CMAKE_SHARED_LIBRARY_SUFFIX}.a DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/flexApp/libflexApp${CMAKE_SHARED_LIBRARY_SUFFIX}.a DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/oauthApp/liboauthApp${CMAKE_SHARED_LIBRARY_SUFFIX}.a DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/markers/libmarkers${CMAKE_SHARED_LIBRARY_SUFFIX}.a DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark/libte_benchmark${CMAKE_SHARED_LIBRARY_SUFFIX}.a DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um/libte_benchmark_um${CMAKE_SHARED_LIBRARY_SUFFIX}.a DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq/libte_benchmark_um_pq${CMAKE_SHARED_LIBRARY_SUFFIX}.a DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/peer-server/libpeer_server${CMAKE_SHARED_LIBRARY_SUFFIX}.a DESTINATION ${PROJECT_NAME}-bin/lib)
	else()
		install(FILES ${PROJECT_BINARY_DIR}/src/modules/libffead-modules${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/src/framework/libffead-framework${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/default/libdefault${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/flexApp/libflexApp${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/oauthApp/liboauthApp${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/markers/libmarkers${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark/libte_benchmark${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um/libte_benchmark_um${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq/libte_benchmark_um_pq${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
		install(FILES ${PROJECT_BINARY_DIR}/web/peer-server/libpeer_server${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
	endif()
	install(FILES ${PROJECT_BINARY_DIR}/ffead-cpp.exe DESTINATION ${PROJECT_NAME}-bin/)
else()
	install(FILES ${PROJECT_BINARY_DIR}/src/modules/libffead-modules${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
	install(FILES ${PROJECT_BINARY_DIR}/src/framework/libffead-framework${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
	install(FILES ${PROJECT_BINARY_DIR}/web/default/libdefault${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
	install(FILES ${PROJECT_BINARY_DIR}/web/flexApp/libflexApp${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
	install(FILES ${PROJECT_BINARY_DIR}/web/oauthApp/liboauthApp${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
	install(FILES ${PROJECT_BINARY_DIR}/web/markers/libmarkers${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
	install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark/libte_benchmark${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
	install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um/libte_benchmark_um${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
	install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq/libte_benchmark_um_pq${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
	install(FILES ${PROJECT_BINARY_DIR}/web/peer-server/libpeer_server${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${PROJECT_NAME}-bin/lib)
	install(FILES ${PROJECT_BINARY_DIR}/ffead-cpp DESTINATION ${PROJECT_NAME}-bin/)
endif()
if(SRV_ALL)
	install(FILES ${PROJECT_SOURCE_DIR}/ffead-cpp-lithium DESTINATION ${PROJECT_NAME}-bin/)
	install(FILES ${PROJECT_SOURCE_DIR}/ffead-cpp-cinatra DESTINATION ${PROJECT_NAME}-bin/)
	install(FILES ${PROJECT_SOURCE_DIR}/ffead-cpp-drogon DESTINATION ${PROJECT_NAME}-bin/)
endif()
install(FILES ${PROJECT_SOURCE_DIR}/script/server_valgrind.sh DESTINATION ${PROJECT_NAME}-bin/)
install(FILES ${PROJECT_SOURCE_DIR}/script/server.sh DESTINATION ${PROJECT_NAME}-bin/)
install(FILES ${PROJECT_SOURCE_DIR}/script/client.pem DESTINATION ${PROJECT_NAME}-bin/)
install(FILES ${PROJECT_SOURCE_DIR}/script/dh1024.pem DESTINATION ${PROJECT_NAME}-bin/)
install(FILES ${PROJECT_SOURCE_DIR}/script/root.pem DESTINATION ${PROJECT_NAME}-bin/)
install(FILES ${PROJECT_SOURCE_DIR}/script/server.pem DESTINATION ${PROJECT_NAME}-bin/)
install(FILES ${PROJECT_SOURCE_DIR}/script/vhost-server.sh DESTINATION ${PROJECT_NAME}-bin/)
